package com.william.springsecurity.service.impl;

import cn.hutool.json.JSONUtil;
import com.william.springsecurity.mapper.UserMapper;
import com.william.springsecurity.pojo.SysPermission;
import com.william.springsecurity.pojo.SysRole;
import com.william.springsecurity.pojo.SysUser;
import com.william.springsecurity.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        SysUser sysUser = userMapper.findByName(s);
        if(Objects.isNull(sysUser)){
            throw new UsernameNotFoundException("用户名或密码错误");
        }
        String authorities = getUserAuthority(sysUser.getId());
        sysUser.setRoles(Arrays.asList(authorities.split(",")));
//        List<GrantedAuthority> grantedAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(authorities);
        String[] split = authorities.split(",");
        return User.withUsername(JSONUtil.toJsonStr(sysUser)).password(sysUser.getPassword()).authorities(split).build();
    }

    // SimpleGrantedAuthority 没有空参构造，无法从redis直接反序列化
    @Override
    @Cacheable(key = "#userId + 'GrantedAuthority'",cacheNames = "GrantedAuthority")
    public String getUserAuthority(Long userId){
        // 角色(Role_xx) 权限sys:user:list
        // Role_admin,Role_user,sys:user:list,sys:user:add
        String authorities = "";
        List<SysRole> roles = userMapper.getUserRoles(userId);
        String roleNames = roles.parallelStream().map(r -> "ROLE_".concat(r.getRoleName())).collect(Collectors.joining(","));
        List<SysPermission> permisson = userMapper.getUserPermission(userId);
        String permissionList = permisson.parallelStream().map(p -> "ROLE_".concat(p.getPermissionValue())).collect(Collectors.joining(","));
        if(StringUtils.isNotBlank(roleNames)){
            authorities = roleNames.concat(",").concat(permissionList);
        }else{
            authorities = permissionList;
        }
        // 角色 权限
        return authorities;
    }

}
